package nyist.media.service.impl;

import nyist.media.entity.ClassRoom;
import nyist.media.entity.RepairRecord;
import nyist.media.entity.admin.Admin;
import nyist.media.entity.admin.Role;
import nyist.media.enums.RepairStatus;
import nyist.media.exception.BusinessException;
import nyist.media.page.ApiResult;
import nyist.media.page.AppPage;
import nyist.media.repository.AdminRepository;
import nyist.media.repository.ClassRoomRepository;
import nyist.media.repository.RepairOrdersRepository;
import nyist.media.repository.RoleRepository;
import nyist.media.service.RepairOrdersService;
import nyist.media.vo.RepairRecordVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dcf
 * @date 2019/3/19
 */
@Service
public class RepairOrdersServiceImpl implements RepairOrdersService {

    @Autowired
    private RepairOrdersRepository repairOrdersRepository;
    @Autowired
    private ClassRoomRepository classRoomRepository;
    @Autowired
    private AdminRepository adminRepository;
    @Autowired
    private RoleRepository roleRepository;

    @Override
    public AppPage<RepairRecordVO> findPageByStatus(PageRequest pageRequest, RepairStatus status) {
        RepairRecord record = new RepairRecord();
        record.setStatus(status);
        return returnData(Example.of(record), pageRequest);
    }

    @Override
    public void rejectedOrder(Long id, String rejectedReason) {
        RepairRecord record = repairOrdersRepository.findOne(id);
        if (!record.getStatus().equals(RepairStatus.WAIT_REPAIR)) {
            throw new BusinessException(ApiResult.REJECTED_HANDLER, "不能重复操作");
        }
        record.setModifyDate(new Date());
        record.setRejectedReason(rejectedReason);
        record.setStatus(RepairStatus.REJECTED);
        repairOrdersRepository.save(record);
    }

    @Override
    public void createRepairOrders(Long id, String txt, Admin currentInfo) {
        Date now = new Date();
        ClassRoom room = classRoomRepository.findOne(id);
        if (room == null) {
            throw new BusinessException(ApiResult.DATA_NOT_FOUND, "教室信息不存在");
        }
        room.setStatus(true);
        room.setModifyDate(now);
        classRoomRepository.save(room);
        createRepairRecords(room, txt, currentInfo, now);
    }

    @Override
    public void deleteById(Long id) {
        RepairRecord record = repairOrdersRepository.findOne(id);
        if (record.getStatus().equals(RepairStatus.REPAIRING)) {
            throw new BusinessException(ApiResult.DELETE_FAIL);
        }
        repairOrdersRepository.delete(record);
    }

    @Override
    public AppPage<RepairRecordVO> findMyPage(PageRequest pageRequest, Admin currentInfo) {
        Boolean isRepairMan = checkRole(currentInfo);
        RepairRecord repairRecord = new RepairRecord();
        if (isRepairMan) {
            repairRecord.setRepairAdmin(currentInfo);
        } else {
            repairRecord.setCommitAdmin(currentInfo);
        }
        return returnData(Example.of(repairRecord), pageRequest);
    }

    @Override
    public void finishedOrders(Long id, Admin currentInfo) {
        Boolean hasPermission = checkRole(currentInfo);
        if (!hasPermission) {
            throw new BusinessException(ApiResult.NO_PERMISSIONS);
        }
        Date now = new Date();
        RepairRecord record = repairOrdersRepository.findOne(id);
        ClassRoom room = record.getRoom();
        room.setStatus(false);
        room.setModifyDate(now);
        classRoomRepository.save(room);

        record.setModifyDate(now);
        record.setRepairDate(now);
        record.setStatus(RepairStatus.REPAIRED);
        record.setRepairDate(new Date());
        repairOrdersRepository.save(record);
    }

    @Override
    public void deliverOrders(Long id, Long repairIds) {
        RepairRecord repairRecord = repairOrdersRepository.findOne(id);
        if (!repairRecord.getStatus().equals(RepairStatus.WAIT_REPAIR)) {
            throw new BusinessException(ApiResult.ORDERS_HANDLED);
        }
        repairRecord.setStatus(RepairStatus.REPAIRING);
        repairRecord.setRepairAdmin(adminRepository.findOne(repairIds));
        repairRecord.setModifyDate(new Date());
        repairOrdersRepository.save(repairRecord);
    }

    @Override
    public RepairRecordVO findOne(Long id) {
        return new RepairRecordVO(repairOrdersRepository.findOne(id));
    }

    /**
     * 检测当前对象是否有维修员权限操作
     * @param currentInfo 当前登录对象
     * @return true 有权限 false 没有权限
     */
    private Boolean checkRole(Admin currentInfo) {
        Role repairRole = roleRepository.findByNameLike("%维修%");
        return currentInfo.getRoles().contains(repairRole);
    }

    /**
     * 查看我的维修单
     * @param example 条件对象
     * @param pageRequest 分页对象
     * @return 我的申请单列表
     */
    private AppPage<RepairRecordVO> returnData(Example<RepairRecord> example, PageRequest pageRequest) {
        Page<RepairRecord> page = repairOrdersRepository.findAll(example, pageRequest);
        List<RepairRecordVO> recordVOS = page.getContent().stream().map(RepairRecordVO::new).collect(Collectors.toList());
        return new AppPage<>(pageRequest, page.getTotalElements(), page.getTotalPages(), recordVOS);
    }

    /**
     * @param now         当前时间
     * @param room        教室
     * @param content     问题描述
     * @param currentInfo 提交对象
     */
    private void createRepairRecords(ClassRoom room, String content, Admin currentInfo, Date now) {
        RepairRecord repairRecord = new RepairRecord();
        repairRecord.setCreateDate(now);
        repairRecord.setModifyDate(now);
        repairRecord.setStatus(RepairStatus.WAIT_REPAIR);
        repairRecord.setText(content);
        repairRecord.setCommitAdmin(currentInfo);
        repairRecord.setRoom(room);
        repairOrdersRepository.save(repairRecord);
    }

}
